<?php defined('SYSPATH') or die('No direct script access.');

class Mailer {

    private $sender; 
    private $recipient; 
    private $subject; 
    private $headers=array(); 
    private $mimeTypes=array(); 
    private $html=array(); 
    private $attachments=array();
    
    public function __construct($sender,$recipient,$subject,$message){
    
        // validate incoming parameters
        
        if(!preg_match("/^.+@.+$/",$sender)){ 
            throw new Exception('Invalid value for email sender.'); 
        }
    
        if(!preg_match("/^.+@.+$/",$recipient)){ 
            throw new Exception('Invalid value for email recipient.'); 
        }
    
        if(!$subject||strlen($subject)>255){ 
            throw new Exception('Invalid length for email subject.'); 
        }
        
        if(!$message){ 
            throw new Exception('Invalid value for email message.'); 
        }
        
        $this->sender=$sender; 
        $this->recipient=$recipient; 
        $this->subject=$subject; 
        $this->message=$message;
        
        // define some default MIME headers
        
        $this->headers['MIME-Version']='1.0'; 
        $this->headers['Content-Type']='multipart/mixed;boundary="MIME_BOUNDRY"'; 
        $this->headers['From']='<'.$this->sender.'>'; 
        $this->headers['Return-Path']='<'.$this->sender.'>'; 
        $this->headers['Reply-To']=$this->sender; 
        $this->headers['X-Mailer']='PHP5'; 
        $this->headers['X-Sender']=$this->sender; 
        $this->headers['X-Priority']='3';
        
        // define some default MIME types
        
        $this->mimeTypes['image/jpeg']='jpg'; 
        $this->mimeTypes['image/jpg']='jpg'; 
        $this->mimeTypes['image/gif']='gif'; 
        $this->mimeTypes['text/plain']='txt'; 
        $this->mimeTypes['text/html']='htm'; 
        $this->mimeTypes['text/xml']='xml'; 
        $this->mimeTypes['application/pdf']='pdf';
        
    }
    
    // add new MIME header
    
    public function addHeader($name,$value){ 
        $this->headers[$name]=$value; 
    }
    
    // add HTML to message
    
    public function addHTML($html){
    
        if(!$html){ 
            throw new Exception('Invalid HTML.'); 
        }
        
        $this->html[]=$html;
    
    }
    
    // add new attachment
    
    public function addAttachment($attachment){
    
        if(!file_exists($attachment)){ 
            throw new Exception('Invalid attachment.'); 
        }
        
        $this->attachments[]=$attachment;
    
    }
    
    // get MIME Type of attachment
    
    private function getMimeType($attachment){
    
        $attachment=explode('.',basename($attachment));
        
        if(!$mimeType=array_search(strtolower($attachment[count($attachment)-
        1]),$this->mimeTypes)){ 
            throw new Exception('MIME Type not found.'); 
        }
        
        return $mimeType;
    
    }
    
    // create message MIME headers
    
    private function buildHeaders(){
    
        foreach($this->headers as $name=>$value){ 
            $headers[]=$name.': '.$value; 
        }
        
        return implode("\n",$headers)."\nThis is a multi-part message in MIME format.\n";
    
    }
    
    // create text part of the message
    
    private function buildTextPart(){
    
        return "--MIME_BOUNDRY\nContent-Type: text/plain; charset=iso-8859-1\n
        Content-Transfer-Encoding: quoted-printable\n\n\n".$this->message."\n\n";
    
    }
    
    // create HTML part of the message
    
    private function buildHTMLPart(){
    
        if(count($this->html)>0){
        
            $htmlPart='';
            
            foreach($this->html as $html){
            
                $htmlPart.="--MIME_BOUNDRY\nContent-Type: text/html; charset=iso-8859-1
            \nContent-Transfer-Encoding: 8bit\n\n\n".$html."\n\n";
            
            }
        
            return $htmlPart;
        
        }
    
    }
    
    // create attachments part of the message
    
    private function buildAttachmentPart(){
    
        if(count($this->attachments)>0){
        
            $attachmentPart='';
            
            foreach($this->attachments as $attachment){
            
                if(!$fileStr=file_get_contents($attachment)){
                
                    throw new Exception('Error reading contents of attachment.');
                
                }
                
                $fileStr=chunk_split(base64_encode($fileStr));
                
                $attachmentPart.="--MIME_BOUNDRY\nContent-Type: ".$this->getMimeType($attachment).
                "; name=\"".basename($attachment)."\"\nContent-disposition: attachment\nContent-Transfer-Encoding: base64\n\n".$fileStr."\n\n";
            
            }
        
            return $attachmentPart;
        
        }
    
    }
    
    // send email
    
    public function send(){
    
        $to=$this->recipient;
        
        $subject=$this->subject;
        
        $headers=$this->buildHeaders();
        
        $message=$this->buildTextPart().$this->buildHTMLPart().$this->buildAttachmentPart()."--MIME_BOUNDRY--\n";
        
        if(!mail($to,$subject,$message,$headers)){
        
            throw new Exception('Error sending email.');
        
        }
    
    }

}
 